home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / umich / utils / nroff~06.zoo / command.c < prev    next >
C/C++ Source or Header  |  1992-07-17  |  37KB  |  1,970 lines

  1. static char *rcsid_command_c="$Id: command.c,v 1.2 1992/07/16 10:38:32 rosenkra Exp $";
  2.  
  3. /*
  4.  * $Log: command.c,v $
  5.  * Revision 1.2  1992/07/16  10:38:32  rosenkra
  6.  * port to gcc, add tm,ie,el
  7.  *
  8.  */
  9.  
  10. /*
  11.  *    command.c - command input parser/processor for nroff text processor
  12.  *
  13.  *    adapted for atariST/TOS by Bill Rosenkranz 11/89
  14.  *    net:    rosenkra@convex.com
  15.  *    CIS:    71460,17
  16.  *    GENIE:    W.ROSENKRANZ
  17.  *
  18.  *    original author:
  19.  *
  20.  *    Stephen L. Browning
  21.  *    5723 North Parker Avenue
  22.  *    Indianapolis, Indiana 46220
  23.  *
  24.  *    history:
  25.  *
  26.  *    - Originally written in BDS C;
  27.  *    - Adapted for standard C by W. N. Paul
  28.  *    - Heavily hacked up to conform to "real" nroff by Bill Rosenkranz
  29.  */
  30.  
  31. #undef NRO_MAIN                    /* extern globals */
  32.  
  33. #include <stdio.h>
  34. #include "nroff.h"
  35.  
  36. #define iscond(x)    ((x)=='>'||(x)=='<'||(x)=='=')
  37. #define isoper(x)    ((x)=='+'||(x)=='-'||(x)=='*'||(x)=='/'||(x)=='%')
  38.  
  39.  
  40. #define MAXCLEV        10
  41.  
  42.                         /* these must be globals: */
  43. static int    take_else[MAXCLEV+1];        /* for ie/el. T -> take el */
  44. static int    do_if[MAXCLEV+1];        /* flag if condition is T */
  45. static int    not_cond[MAXCLEV+1];        /* flag if !condition */
  46. static int    clev = 0;            /* comand() is recursive. */
  47.                         /* this is current level */
  48.  
  49.  
  50. /*------------------------------*/       
  51. /*    comand            */
  52. /*------------------------------*/       
  53. void comand (p)
  54. REGISTER char  *p;
  55. {
  56.  
  57. /*
  58.  *    main command processor
  59.  */
  60.  
  61.     REGISTER int    i;
  62.     REGISTER int    ct;
  63.     REGISTER int    val;
  64.     REGISTER int       indx;
  65.     int         spval;
  66.     char        argtyp;
  67.     char        name[MAXLINE];
  68.     char        macexp[MXMLEN];
  69.     char        slenstr[MXMLEN];
  70.     int        slen;
  71.     int        tmp;
  72.     char           *pfs;
  73.     char        fs[20];
  74.     char        c;
  75.     char           *ps1;
  76.     char           *ps2;
  77.  
  78.     int        sv_escon;
  79.     char        wrdbuf[MAXLINE];
  80.  
  81.  
  82.     if (debugging)
  83.         fprintf (dbg_stream,
  84.         "***%s.comand: enter, clev=%d, p=|%s|\n",myname,clev+1,p);
  85.  
  86.  
  87.     /*
  88.      *   if ".    xx", skip blanks
  89.      */
  90.     if (*(p+1) == ' ' || *(p+1) == '\t')
  91.     {
  92.         p    = skipbl (++p);
  93.         *--p = dc.cmdchr;
  94.     }
  95.  
  96.  
  97.     /*
  98.      *   get command code
  99.      */
  100.     ct = comtyp (p, macexp);
  101.  
  102.  
  103.     /*
  104.      *   error?
  105.      */
  106.     if (ct == UNKNOWN)
  107.     {
  108.         fprintf (err_stream,
  109.             "***%s: unrecognized command %s\n", myname, p);
  110.         return;
  111.     }
  112.  
  113.  
  114.     /*
  115.      *   ignore comments
  116.      */
  117.     if (ct == COMMENT)
  118.     {
  119.         return;
  120.     }
  121.  
  122.  
  123.     /*
  124.      *   bump command level (keep track of recursion). remember to dec
  125.      *   when this routine returns. so far we only need this for ie/el
  126.      *   processing since we need to track the state of the .ie condition.
  127.      */
  128.     clev++;
  129.  
  130.  
  131.     /*
  132.      *   do escape expansion on command line args
  133.      */
  134.     expesc (p, name);
  135.  
  136.  
  137.     /*
  138.      *   get value of command
  139.      */
  140. /*    val = getval (p, &argtyp);*/
  141.  
  142.  
  143.  
  144.  
  145.     /*
  146.      *   do the command
  147.      */
  148.     switch (ct)
  149.     {
  150.     /* set (¶m, val, type, defval, minval, maxval) */
  151.     case FC:
  152.         /*
  153.          *   field delim/pad chars
  154.          *
  155.          *   .fc [delim] [pad]
  156.          */
  157.         fprintf (err_stream, "***%s: .fc not available\n", myname);
  158.         break;
  159.     case TR:
  160.         /*
  161.          *   translate
  162.          *
  163.          *   .tr ab...
  164.          */
  165.         fprintf (err_stream, "***%s: .tr not available\n", myname);
  166.         break;
  167.  
  168.  
  169.  
  170.  
  171. /*NEW @ 1.2.0 */
  172.     case HY:
  173.         /*
  174.          *   hyphenate
  175.          *
  176.          *   .hy code
  177.          *
  178.          *   for now code is really ignored unless 0 or 1.
  179.          */
  180.         val = getval (p, &argtyp);
  181.         hyphenating = val;
  182.         break;
  183.     case NH:
  184.         /*
  185.          *   not hyphenate
  186.          *
  187.          *   .nh
  188.          */
  189.         hyphenating = 0;
  190.         break;
  191.     case HC:
  192.         /*
  193.          *   hyphenate char
  194.          *
  195.          *   .hc c
  196.          */
  197.         val = getval (p, &argtyp);
  198.         if (argtyp == '\r' || argtyp == '\n')
  199.             hyph_char = '%';
  200.         else
  201.             hyph_char = argtyp;
  202.         break;
  203.     case HW:
  204.         /*
  205.          *   hyphenate words (IGNORED)
  206.          *
  207.          *   .hw list
  208.          */
  209.         break;
  210.     case TM:
  211.         /*
  212.          *   terminal message
  213.          *
  214.          *   .tm string
  215.          */
  216.         val = getval (p, &argtyp);
  217.         p = skipwd (p);
  218.         p = skipbl (p);
  219.  
  220.         /*
  221.          *   force escape parsing, saving old setting
  222.          */
  223.         sv_escon = dc.escon;
  224.         dc.escon = YES;
  225.  
  226.         /*
  227.          *   expand escape sequences
  228.          */
  229.         expesc (p, wrdbuf);
  230.  
  231.         /*
  232.          *   print it (to stderr, has \n already)...
  233.          */
  234.         fprintf (stderr, "%s", wrdbuf);
  235.  
  236.         /*
  237.          *   reset escape sequence processing
  238.          */
  239.         dc.escon = sv_escon;
  240.         break;
  241.     case AD:
  242.         /*
  243.          *   adjust
  244.          *
  245.          *   .ad [mode]
  246.          */
  247.         val = getval (p, &argtyp);
  248.         p = skipwd (p);
  249.         p = skipbl (p);
  250.  
  251.         switch (*p)
  252.         {
  253.         case 'l':
  254.             dc.adjval = ADJ_LEFT;
  255.             dc.juval  = YES;
  256.             break;
  257.         case 'r':
  258.             dc.adjval = ADJ_RIGHT;
  259.             dc.juval  = YES;
  260.             break;
  261.         case 'c':
  262.             dc.adjval = ADJ_CENTER;
  263.             dc.juval  = YES;
  264.             break;
  265.         case 'b':
  266.         case 'n':
  267.             dc.adjval = ADJ_BOTH;
  268.             dc.juval  = YES;
  269.             break;
  270.         default:
  271.             break;
  272.         }
  273.         break;
  274.     case AF:
  275.         /*
  276.          *   assign format to number reg
  277.          *
  278.          *   .af R {1,a,A,i,I,0...1}
  279.          */
  280.         val = getval (p, &argtyp);
  281.         p = skipwd (p);
  282.         p = skipbl (p);
  283.         if (!isalpha (*p))
  284.         {
  285.             fprintf (err_stream,
  286.                 "***%s: invalid or missing number register name\n",
  287.                 myname);
  288.         }
  289.         else
  290.         {
  291.             /*
  292.              *   number register format is 1,a,A,i,I,0...1
  293.              *   default is 1. for 0001 format, store num dig
  294.              *   or'ed with 0x80, up to 8 digits.
  295.              */
  296.             indx = tolower (*p) - 'a';
  297.             p = skipwd (p);
  298.             p = skipbl (p);
  299.             if (*p == '1')
  300.                 dc.nrfmt[indx] = '1';
  301.             else if (*p == 'a')
  302.                 dc.nrfmt[indx] = 'a';
  303.             else if (*p == 'A')
  304.                 dc.nrfmt[indx] = 'A';
  305.             else if (*p == 'i')
  306.                 dc.nrfmt[indx] = 'i';
  307.             else if (*p == 'I')
  308.                 dc.nrfmt[indx] = 'I';
  309.             else if (*p == '0')
  310.             {
  311.                 for (i = 0; isdigit (p[i]); i++)
  312.                     ;
  313.                 dc.nrfmt[indx] = (char) (i);
  314.                 if (dc.nrfmt[indx] <= 0)
  315.                     dc.nrfmt[indx] = '1';
  316.                 else if (dc.nrfmt[indx] > 8)
  317.                 {
  318.                     dc.nrfmt[indx]  = 8;
  319.                     dc.nrfmt[indx] |= 0x80;
  320.                 }
  321.                 else
  322.                     dc.nrfmt[indx] |= 0x80;
  323.  
  324.             }
  325.             else
  326.                 dc.nrfmt[indx] = '1';
  327.         }
  328.         break;
  329.     case BD:
  330.         /*
  331.          *   embolden font (IGNORED)
  332.          *
  333.          *   .bd [S] F N
  334.          */
  335.         break;
  336.     case BO:
  337.         /*
  338.          *   bold face
  339.          *
  340.          *   .bo [N]
  341.          */
  342.         val = getval (p, &argtyp);
  343.         set (&dc.boval, val, argtyp, 1, 0, HUGE);
  344.         dc.cuval = dc.ulval = 0;
  345.         break;
  346.     case BP:
  347.         /*
  348.          *   begin page
  349.          *
  350.          *   .bp [+/-N]
  351.          */
  352.         val = getval (p, &argtyp);
  353.         if (pg.lineno > 0)
  354.             space (HUGE);
  355.         set (&pg.curpag, val, argtyp, pg.curpag + 1, -HUGE, HUGE);
  356.         pg.newpag = pg.curpag;
  357.         set_ireg ("%", pg.newpag, 0);
  358.         break;
  359.     case BR:
  360.         /*
  361.          *   break (page)
  362.          *
  363.          *   .br
  364.          */
  365.         robrk ();
  366.         break;
  367.     case BS:
  368.         /*
  369.          *   backspc in output
  370.          *
  371.          *   .bs [N]
  372.          */
  373.         val = getval (p, &argtyp);
  374.         set (&dc.bsflg, val, argtyp, 1, 0, 1);
  375.         break;
  376.     case C2:
  377.         /*
  378.          *   nobreak char
  379.          *
  380.          *   .c2 [c=']
  381.          */
  382.         val = getval (p, &argtyp);
  383.         if (argtyp == '\r' || argtyp == '\n')
  384.             dc.nobrchr = '\'';
  385.         else
  386.             dc.nobrchr = argtyp;
  387.         break;
  388.     case CC:
  389.         /*
  390.          *   command character
  391.          *
  392.          *   .cc [c=.]
  393.          */
  394.         val = getval (p, &argtyp);
  395.         if (argtyp == '\r' || argtyp == '\n')
  396.             dc.cmdchr = '.';
  397.         else
  398.             dc.cmdchr = argtyp;
  399.         break;
  400.     case CE:
  401.         /*
  402.          *   center
  403.          *
  404.          *   .ce [N]
  405.          */
  406.         val = getval (p, &argtyp);
  407.         robrk ();
  408.         set (&dc.ceval, val, argtyp, 1, 0, HUGE);
  409.         break;
  410.     case CS:
  411.         /*
  412.          *   constant space char (IGNORED)
  413.          *
  414.          *   .cs F N M
  415.          */
  416.         break;
  417.     case CU:
  418.         /*
  419.          *   continuous underline
  420.          *
  421.          *   .cu [N]
  422.          */
  423.         val = getval (p, &argtyp);
  424.         set (&dc.cuval, val, argtyp, 1, 0, HUGE);
  425.         dc.ulval = dc.boval = 0;
  426.         break;
  427.     case DE:
  428.         /*
  429.          *   define macro
  430.          *
  431.          *   .de name [end]
  432.          */
  433.         val = getval (p, &argtyp);
  434.         ignoring = FALSE;
  435.         defmac (p, sofile[dc.flevel]);
  436.         break;
  437.     case DS:
  438.         /*
  439.          *   define string
  440.          *
  441.          *   .ds name string
  442.          */
  443.         val = getval (p, &argtyp);
  444.         defstr (p);
  445.         break;
  446.     case EC:
  447.         /*
  448.          *   escape char
  449.          *
  450.          *   .ec [c=\]
  451.          */
  452.         val = getval (p, &argtyp);
  453.         if (argtyp == '\r' || argtyp == '\n')
  454.             dc.escchr = '\\';
  455.         else
  456.             dc.escchr = argtyp;
  457.         dc.escon = YES;
  458.         break;
  459.     case EF:
  460.         /*
  461.          *   even footer
  462.          *
  463.          *   .ef "a" "b" "c"
  464.          */
  465.         val = getval (p, &argtyp);
  466.         gettl (p, pg.efoot, &pg.eflim[0]);
  467.         break